#ifndef RENDERER_H
#define RENDERER_H

#include <stack>
#include <wx/artprov.h>
#include <wx/xrc/xmlres.h>
#include <wx/string.h>
#include <wx/bitmap.h>
#include <wx/image.h>
#include <wx/icon.h>
#include <wx/menu.h>
#include <wx/gdicmn.h>
#include <wx/font.h>
#include <wx/colour.h>
#include <wx/settings.h>
#include <wx/filepicker.h>
#include <wx/toolbar.h>
#include <wx/statusbr.h>
#include <wx/panel.h>
#include <wx/propgrid/propgrid.h>
#include <wx/propgrid/advprops.h>
#include <wx/sizer.h>
#include <wx/splitter.h>
#include <wx/frame.h>

#include "Common/Common.h"

class Renderer {
public:
	Renderer();
	~Renderer();

	inline wxColor GetBgColor( ) const {return _bgColor;}
	inline void SetBgColor( const wxColor& color ) {_bgColor = color;}

	void Resize( int width, int height );
	void BeginDraw();
	void EndDraw();

	Transform GetCamera() const;
	void SetCamera( const Transform& camera );

	void Push();
	void Pop();
	void Load( const Matr4& model );
	void Mult( const Matr4& model );

	void DrawPoint( wxPaintDC& dc, const Vec2& point, const wxColor& color );
	void DrawLine( wxPaintDC& dc, const Vec2& start, const Vec2& end, const wxColor& color );
	void DrawPolygon( wxPaintDC& dc, const IIterable<Vec2>* vertices, const wxColor& color );
	void DrawCircle( wxPaintDC& dc, const Vec2& center, float radius, const wxColor& color );

	Vec2 GetWorldCoords(const wxPoint& screen) const;
private:
	void Frustum( float left, float right, float top, float bottom);

	inline int GetWidth() const { return _width; }
	inline void SetWidth( int value ) { _width = value; }

	inline int GetHeight() const { return _height; }
	inline void SetHeight( int value ) { _height = value; }

	Vec4 WorldToCam(const Vec2& world) const;
	Vec4 CamToProjecion(const Vec4& cam) const;
	wxPoint ProjecionToScreen( const Vec4& projecion ) const;

	Vec4 ScreenToProjecion(const wxPoint& screen) const;
	Vec4 ProjecionToCam(const Vec4& projecion) const;
	Vec2 CamToWorld(const Vec4& cam) const;

private:
	std::stack<Matr4> _matrStack;

	wxColor _bgColor;

	Matr4 _modelMatr;
	Matr4 _projectionMatr;

	int _width;
	int _height;

	Transform _camera;
};

#endif // RENDERER_H
